package lifo.GammaTaf.GammaPomset;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public interface GammaPomset {
	public void accepteVisiteur(VisitorGammaRegularExpression visitor);
	
	public static class Action implements GammaPomset {
		Set<Integer> alpha;
		Set<Integer> beta;
		public boolean[] pre;
		public boolean[] post;
		public String arg;
	
		public Action(boolean[] pre, String arg, boolean[] post) {
			super();
			this.pre = pre;
			this.post = post;
			this.arg = arg;
		}
		
		/**
		 * Constructeur recevant un élément de gamma pomset en tant que string
		 * @param element : élément d'un Gamma Pomset sous le format (α,a,β)
		 *                  α et β pouvant être écrit sous forme ensembliste (avec { et } ).
		 */
		public Action(String element){
			alpha= new HashSet<Integer>();
			beta= new HashSet<Integer>();
			Pattern p = Pattern.compile("\\d+"); 
			String[] tab=element.split("(\\},)|(,\\{)", 3);
			Matcher m = p.matcher(tab[0]); // pour récupérer les entiers de l'ensemble pre
			int i=0;
			pre= new boolean[tab[0].length()-1];
			while(m.find()){
				pre[i]= true;
                alpha.add(Integer.parseInt(m.group()));
                i++;
			}
			m = p.matcher(tab[2]); // pour récupérer les entiers de l'ensemble post
			post= new boolean[tab[2].length()-1];
			i=0;
			while(m.find()){ 
				   post[i]=true;
				   beta.add(Integer.parseInt(m.group()));
				   i++;
			}
			arg= tab[1];
		}

		public void accepteVisiteur(VisitorGammaRegularExpression visitor) {
			visitor.visiteAction(this);
		}
		
		public String toString() {
			return "(" + toString(pre) + "," + arg + "," + toString(post) + ")";
		}	

		private static String toString(boolean[] tab) {
			StringBuffer res = new StringBuffer();
			res.append('{');
			for (int i=0; i<tab.length; i++)
				if (tab[i])
					res.append(i + ",");
			res.deleteCharAt(res.lastIndexOf(","));//supprimer la dernière virgule
			res.append('}');
			return res.toString();
		}	
	}
	
	public static class Sum implements GammaPomset {
		public GammaPomset[] arg;

		public Sum(GammaPomset[] arg) {
			super();
			this.arg = arg;
		}

		public void accepteVisiteur(VisitorGammaRegularExpression visitor) {
			visitor.visiteSum(this);
		}

		public String toString() {
			String retour="";
			for(GammaPomset gp: arg){
				retour += "+"+gp.toString();
			}
			return retour.replaceFirst("\\+", "");
		}
	}

	public static class Star implements GammaPomset {
		public GammaPomset arg;
		
		public Star(GammaPomset arg) {
			super();
			this.arg = arg;
		}

		public void accepteVisiteur(VisitorGammaRegularExpression visitor) {
			visitor.visiteStar(this);
		}

		public String toString() {
			return "*" + arg;
		}

	}
	
	public static class Serie implements GammaPomset {
		public GammaPomset[] arg;

		public Serie(GammaPomset[] arg) {
			super();
			this.arg = arg;
		}

		public void accepteVisiteur(VisitorGammaRegularExpression visitor) {
			visitor.visiteSerie(this);
		}
		
		public String toString() {
			String retour="";
			for(GammaPomset gp: arg){
				retour += "."+gp.toString();
			}
			return retour.replaceFirst(".", "");
		}

	}

}
